//-----------------------------------------------------------------------
//  This file is part of: 
//  Visual Studio Team Edition for Database Professionals
// 
//  Copyright (C) Microsoft Corporation.  All rights reserved.
// 
//  This source code is intended only as a supplement to Microsoft
//  Development Tools and/or on-line documentation.  See these other
//  materials for detailed information regarding Microsoft code samples.
//  
//  THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//  PARTICULAR PURPOSE.
//-----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;

using System.Data;
using System.Data.Common;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Globalization;
using TestTools = Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TeamSystem.Data.UnitTesting;
using Microsoft.VisualStudio.TeamSystem.Data.UnitTesting.Conditions;

namespace TestConditions
{
    /// <summary>
    /// RowsAffectedCondition verifies that the number
    /// of rows affected for a specified statement equals the expected number.
    /// </summary>
    [DisplayName("Rows Affected")]
    public class RowsAffectedCondition : TestCondition
    {
        private int _batch;
        private int _statement; 
        private int _count;
        
        public RowsAffectedCondition()
        {
            _batch = 1;
            _statement = 1; 
            _count = 0;
        }

        #region Properties

        /// <summary>
        /// Property specifying
        /// statement for which rows affected is being checked
        /// </summary>
        [Category("Test Condition")]
        [DisplayName("Statement")]
        [Description("SQL Statement Number")]
        public int Statement
        {
            get { return _statement; }

            set
            {
                //basic validation
                if (value < 1)
                    throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Statement number cannot be less than 1"));

                _statement = value;
            }
        }

        /// <summary>
        /// Property specifying
        /// expected rows affected count
        /// </summary>
        [Category("Test Condition")]
        [DisplayName("Count")]
        [Description("Rows Affected Count")]
        public int Count
        {
            get { return _count; }

            set
            {
                //basic validation
                if (value < 0)
                    throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Count cannot be less than 0"));

                _count = value;
            }
        }

        #endregion

        /// <summary>
        /// Method you need to override to perform the condition verification
        /// </summary>
        /// <param name="validationConnection">Database unit tests target connection string</param>
        /// <param name="results">Results returned from executing test script</param>
        public override void Assert(DbConnection validationConnection, ExecutionResult[] results)
        {
            //call base for parameter validation
            base.Assert(validationConnection, results);

            //verify batch exists
            if (results.Length < _batch)
                throw new TestTools.AssertFailedException(String.Format(CultureInfo.CurrentCulture, "Batch {0} does not exist", _batch));

            ExecutionResult result = results[_batch - 1];

            //verify statement exists
            if (result.RowsAffected.Length < Statement)
                throw new TestTools.AssertFailedException(String.Format(CultureInfo.CurrentCulture, "Statement {0} does not exist", Statement));

            int statementRowsAffected = result.RowsAffected[Statement - 1];

            //actual condition verification
            //verify statement has expected rows affected
            if (statementRowsAffected != Count)
                throw new TestTools.AssertFailedException(String.Format(CultureInfo.CurrentCulture, "Rows Affected Count {0} does not match {1} expected",
                    statementRowsAffected, Count));
        }

        /// <summary>
        /// This method is called to provide the string shown in the
        /// test conditions panel grid describing what the condition tests
        /// </summary>
        /// <returns>String describing what the condition tests</returns>
        public override string ToString()
        {
            return String.Format(
                CultureInfo.CurrentCulture, 
                "Condition fails if Rows Affected Count for Statement {0} does not equal {1}",
                Statement, Count);
        }

    }
}
